package cn.signalpha.modules.shop.service;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.signalpha.common.cache.ConfigCache;
import cn.signalpha.common.cache.ConfigKeys;
import cn.signalpha.common.dto.ConfigDTO;
import cn.signalpha.common.utils.Arith;
import cn.signalpha.core.http.util.HttpUtil;
import cn.signalpha.core.log.exception.ServiceException;
import cn.signalpha.core.tool.jackson.JsonUtil;
import cn.signalpha.core.tool.utils.*;
import cn.signalpha.modules.shop.entity.Order;
import cn.signalpha.modules.shop.entity.Seller;
import cn.signalpha.modules.shop.entity.UserAddress;
import cn.signalpha.modules.shop.vo.OrderDeliveryVO;
import cn.signalpha.modules.shop.vo.OrderGoodsVO;
import cn.signalpha.modules.shop.vo.SellerDeliveryConfigVO;
import com.alibaba.druid.support.json.JSONUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 同城配送
 * 云昊配送平台接口：<a href="https://shimo.im/docs/T7AiNPLoQO0JCex1/read">...</a>
 *
 * @author signalpha
 */
@Slf4j
@Service
@AllArgsConstructor
public class CityDeliveryService {

	private final SellerService sellerService;
	private final OrderDetailService orderDetailService;

    /**
     * 门店创建
     */
    public Map<String, Object> createSeller(String sellerId, String name, String sellerMobile, String addressMobile, String address, String lng, String lat){
		ConfigDTO.CityDeliveryDTO config = ConfigCache.getObject(ConfigKeys.CITY_DELIVERY, ConfigDTO.CityDeliveryDTO.class);

		Map<String, Object> data = new HashMap<>();
		data.put("client_name", name);
		data.put("client_code", sellerId);
		data.put("phone", addressMobile);
		data.put("address", address);
		data.put("map_lng", lng);
		data.put("map_lat", lat);

		Map<String, Object> params = new HashMap<>();
		params.put("app_id", config.getAppId());
		params.put("timestamp", System.currentTimeMillis() / 1000);
		params.put("mobile", sellerMobile);
		params.put("third_shop_id", sellerId);
		params.put("data", JsonUtil.toJson(data));

		String paramStr = config.getAppSecret().concat(createLinkString(params)).concat(config.getAppSecret());
		params.put("signature", DigestUtil.md5Hex(paramStr).toUpperCase());
		params.put("data", data);

		String resultStr = HttpUtil.postJson(config.getDomain() + "/open/shop/create", JsonUtil.toJson(params));
		Map<String, Object> resultMap = JsonUtil.toMap(resultStr);
		if(ObjectUtil.isEmpty(resultMap) || ObjectUtil.isEmpty(resultMap.get("code")) ){
			log.error("同城配送创建门店失败，请求参数：[{}]， 响应参数：[{}]", params, resultStr);
			throw new ServiceException("同城配送创建门店失败，失败原因：" + resultStr);
		}
		if(!"0".equals(String.valueOf(resultMap.get("code")))){
			log.error("同城配送创建门店失败，请求参数：[{}]， 响应参数：[{}]", params, resultStr);
			throw new ServiceException("同城配送创建门店失败，失败原因：" + resultMap.get("msg"));
		}
        return resultMap;
    }

	/**
	 * 门店信息修改
	 */
	public Map<String, Object> updateSeller(String shopId, String name, String mobile, String address, String lng, String lat){
		ConfigDTO.CityDeliveryDTO config = ConfigCache.getObject(ConfigKeys.CITY_DELIVERY, ConfigDTO.CityDeliveryDTO.class);

		Map<String, Object> data = new HashMap<>();
		data.put("client_name", name);
		data.put("phone", mobile);
		data.put("address", address);
		data.put("map_lng", lng);
		data.put("map_lat", lat);

		Map<String, Object> params = new HashMap<>();
		params.put("app_id", config.getAppId());
		params.put("timestamp", System.currentTimeMillis() / 1000);
		params.put("mobile", mobile);
		params.put("shop_id", shopId);
		params.put("data", JsonUtil.toJson(data));

		String paramStr = config.getAppSecret().concat(createLinkString(params)).concat(config.getAppSecret());
		params.put("signature", DigestUtil.md5Hex(paramStr).toUpperCase());
		params.put("data", data);

		String resultStr = HttpUtil.postJson(config.getDomain() + "/open/shop/update", JsonUtil.toJson(params));
		Map<String, Object> resultMap = JsonUtil.toMap(resultStr);
		if(ObjectUtil.isEmpty(resultMap) || ObjectUtil.isEmpty(resultMap.get("code")) ){
			log.error("同城配送更新门店失败，请求参数：[{}]， 响应参数：[{}]", params, resultStr);
			throw new ServiceException("同城配送更新门店失败，失败原因：" + resultStr);
		}
		if(!"0".equals(String.valueOf(resultMap.get("code")))){
			log.error("同城配送更新门店失败，请求参数：[{}]， 响应参数：[{}]", params, resultStr);
			throw new ServiceException("同城配送更新门店失败，失败原因：" + resultMap.get("msg"));
		}
		return resultMap;
	}

	/**
	 * 推送订单
	 */
	public Map<String, Object> pushOrder(Order order){
		ConfigDTO.CityDeliveryDTO config = ConfigCache.getObject(ConfigKeys.CITY_DELIVERY, ConfigDTO.CityDeliveryDTO.class);
		UserAddress userAddress = JsonUtil.parse(order.getLogisticsInfo(), UserAddress.class);
		OrderDeliveryVO orderDeliveryVO = JsonUtil.parse(order.getLogisticsDeliveryInfo(), OrderDeliveryVO.class);
		Seller seller = sellerService.getById(order.getSellerId());
		SellerDeliveryConfigVO sellerDeliveryConfig = JsonUtil.parse(seller.getDeliveryConfig(), SellerDeliveryConfigVO.class);

		List<Map<String, Object>> productList = new LinkedList<>();
		orderDetailService.listByOrderNo(order.getOrderNo()).forEach(orderDetail -> {
			OrderGoodsVO orderGoodsVO = orderDetail.getGoods();
			String goodsName = StrUtil.hide(orderGoodsVO.getName(), 1, orderGoodsVO.getName().length());
			Map<String, Object> product = new HashMap<>();
			product.put("buy_num", orderDetail.getGoodsNum());
			product.put("buy_price", NumberUtil.decimalFormat(StringPool.HASH, orderDetail.getOrderPrice()));
			product.put("origin_price", NumberUtil.decimalFormat(StringPool.HASH, orderDetail.getGoodsPrice()));
			product.put("is_product", 1);
			product.put("product_name", StringUtil.format("{}-货架号：[{}]", goodsName, orderGoodsVO.getSn()));
			product.put("extend_name", StringUtil.format("货架号：[{}]", orderGoodsVO.getSn()));
			productList.add(product);
		});

		Map<String, Object> data = new HashMap<>();
		data.put("status", "unknown");
		data.put("send_status", "unknown");
		data.put("pay_status", order.getPayStatus() == 0 ? "unknown" : "success");
		data.put("service_type", "arrived");
		data.put("plat_num", order.getId().toString());
		data.put("order_no", order.getOrderNo());
		data.put("buyer_name", userAddress.getConsignee());
		data.put("buyer_phone", userAddress.getMobile());
		data.put("buyer_address", userAddress.getAddress());
		data.put("map_address", userAddress.getAddress());
		data.put("buyer_lng", Func.toStrWithEmpty(userAddress.getLng(), StringPool.EMPTY));
		data.put("buyer_lat", Func.toStrWithEmpty(userAddress.getLat(), StringPool.EMPTY));
		data.put("required", order.getBuyerRemark());
		data.put("is_send_appoint", 1);
		data.put("good_time", DateUtil.parse(orderDeliveryVO.getDeliveryDate() + " " + orderDeliveryVO.getDeliveryEndTime(), DatePattern.NORM_DATETIME_MINUTE_FORMAT).getTime() / 1000);
		data.put("created_at", order.getCreateTime().getTime()/ 1000);
		data.put("origin_amount", NumberUtil.decimalFormat(StringPool.HASH, order.getGoodsPrice()));
		data.put("product_amount", NumberUtil.decimalFormat(StringPool.HASH, order.getOrderPrice()));
		data.put("product_num", order.getGoodsNum());
		data.put("box_amount", 0);
		data.put("send_amount", NumberUtil.decimalFormat(StringPool.HASH, order.getLogisticsFee()));
		data.put("order_amount", NumberUtil.decimalFormat(StringPool.HASH, Arith.add(order.getOrderPrice(), order.getLogisticsFee())));
		data.put("income_amount", NumberUtil.decimalFormat(StringPool.HASH, order.getOrderPrice()));
		data.put("discount_amount", 0);
		data.put("service_amount", 0);
		data.put("is_invoice", 0);
		data.put("invoice_name", StrUtil.hide(order.getGoodsName(), 1, order.getGoodsName().length()));
		data.put("products", productList);

		Map<String, Object> params = new HashMap<>();
		params.put("app_id", config.getAppId());
		params.put("timestamp", System.currentTimeMillis() / 1000);
		params.put("shop_id", sellerDeliveryConfig.getShopId());
		params.put("open_id", sellerDeliveryConfig.getOpenId());
		params.put("order", JSONUtils.toJSONString(data));

		String paramStr = config.getAppSecret().concat(createLinkString(params)).concat(config.getAppSecret());
		params.put("signature", DigestUtil.md5Hex(paramStr).toUpperCase());
		params.put("order", data);

		String resultStr = HttpUtil.postJson(config.getDomain() + "/open/order/create", JsonUtil.toJson(params));
		log.info("同城配送订单推送，请求参数：{}， 响应参数：{}", JsonUtil.toJson(params), resultStr);
		Map<String, Object> resultMap = JsonUtil.toMap(resultStr);
		if(ObjectUtil.isEmpty(resultMap) || ObjectUtil.isEmpty(resultMap.get("code")) ){
			throw new ServiceException("同城配送订单推送失败，失败原因：" + resultStr);
		}
		if(!"0".equals(String.valueOf(resultMap.get("code")))){
			throw new ServiceException("同城配送订单推送失败，失败原因：" + resultMap.get("msg"));
		}
		return resultMap;
	}


	/**
	 * 把数组所有元素字典序排序
	 */
	private String createLinkString(Map<String, Object> params) {
		List<String> keys = new ArrayList<>(params.keySet());
		Collections.sort(keys);
		StringBuilder content = new StringBuilder();
		for (String key : keys) {
			String value = String.valueOf(params.get(key));
			content.append(key).append("=").append(value);
		}
		return content.toString();
	}

	/**
	 * 参数排序
	 */
	private Map<String, Object> paramsSort(Map<String, Object> params) {
		Map<String, Object> result = new HashMap<>();
		List<String> keys = new ArrayList<>(params.keySet());
		Collections.sort(keys);
		for (String key : keys) {
			result.put(key, params.get(key));
		}
		return result;
	}

}
